class Animal {
   // 默认访问权限为public
   // private name: string;
   // name: string;

   /* 
    public=实例属性的访问修饰符
    定义name为实例属性 name:string
    规定name在Animal类的作用域内外皆可访问 
    (protected:只能在Animal及其子类的作用域内访问实例属性name)
    (private:只能在Animal作用域内访问实例属性name)
    默认name属性与当前实例绑定：this.name = name
    PS: 凡是拿不准实例属性的访问权限的情况下 就直接public完事！
    */
   constructor(public name: string) {
      // this.name = name;
   }

   protected move(distanceInMeters: number = 0) {
      console.log(this.name);
      console.log(`${this.name} moved ${distanceInMeters}m.`);
   }
}

/* 继承的语法，除了类型注解（type annotation）外与JS一模一样 */
class Snake extends Animal {
   constructor(name: string) {
      super(name);
   }
   
   public move(distanceInMeters = 5) {
      console.log("Slithering...");

      // 属性“name”为私有属性，只能在类“Animal”中访问。ts(2341)
      console.log(this.name);
      super.move(distanceInMeters);
   }
}

let sam = new Snake("Sammy the Python");
sam.move(5)

// 属性“name”为私有属性，只能在类“Animal”中访问。ts(2341)
console.log(sam.name);
